Guncho Mockup by Guncho Cabal begins here.

"This extension implements mockups of the Guncho programming interface, to make it possible to develop Guncho games offline."

Use authorial modesty.
Use full-length room descriptions.
Use dynamic memory allocation of at least 16384.
Use MAX_STATIC_DATA of 500000.

Part 1 - Player characters

Chapter 1 - The PC kind

A PC is a kind of person. A PC is usually proper-named.

A PC has indexed text called the mud-name. Rule for printing the name of a PC (called whoever) (this is the PC name printing rule): say mud-name of whoever. Understand the mud-name property as describing a PC.

The description of a PC is "[possibly customized description of the item described]".

After examining a PC (this is the list PC possessions after examining rule):
    if the noun is wearing something, say "[The noun] is wearing [a list of things worn by the noun.";
    if the noun is carrying something, say "[The noun] is carrying [a list of things carried by the noun]."

To say possibly customized description of (victim - PC):
	say "This is where [the victim]'s customized description would go."

Mud-naming relates indexed text (called the name) to a PC (called whomever) when the name is the mud-name of whomever. The verb to name (it names, they name, it named, it is named) implies the mud-naming relation.

The PC-corral is a container.

Definition: a PC is connected if it is not in the PC-corral.
Definition: a PC is disconnected if it is in the PC-corral.

To transfer consciousness from (source - a PC) to (target - PC):
	say "{Transferring consciousness from [the source] to [the target]...}";
	if source is the player, change the player to target.

[ mockup PC... ]

Mockup_self is a PC with mud-name "Author". The player is mockup_self.

Chapter 2 - Special input handling

[omitted]

Chapter 3 - Special output handling

[BUGFIX: 5J39 contains a bug where passing indexed text from one phrase to another can cause I6 compilation errors when the second phrase has parameters that are runtime type checked. The "target" parameters here should be typed PC, but they're objects instead to work around this bug.]

To tell (message - indexed text) to (target - an object):
	say "{To [the target]: [message]}";
	say line break.

To tell (message - indexed text) to everyone else near (target - an object):
	say "{To everyone else near [the target]: [message]}";
	say line break.

To tell (message - indexed text) to everyone who can see (spectacle - an object), except the actor:
	say "{To everyone who can see [the spectacle]";
	if except the actor, say ", except the actor";
	say ": [message]}";
	say line break.

To announce (message - indexed text):
	say "{To everyone in the realm: [message]}";
	say line break.

Chapter 4 - Winning and losing

Use competitive scoring translates as (- Constant COMPETITIVE_SCORING; -).

The new obituary headline rule corresponds to routine OBIT_HEAD_NEW. The new obituary headline rule is listed instead of the print obituary headline rule in the for printing the player's obituary rules.

Include (- Replace AfterGameOver; -) before the library.

Include (-
[ OBIT_HEAD_NEW;
    #Ifdef TARGET_ZCODE;
    #IfV5; style bold; #Endif; ! V5
    #Ifnot; ! TARGET_GLULX
    glk($0086, 5); ! set alert style
    #Endif; ! TARGET_
    print "***";
    #ifdef COMPETITIVE_SCORING;
    if (deadflag == 1) print " ", (the) player, " has lost ";
    if (deadflag == 2) print " ", (the) player, " has won ";
    #ifnot; ! cooperative scoring
    if (deadflag == 1) print " You have lost ";
    if (deadflag == 2) print " You have won ";
    #endif; ! scoring type
    if (deadflag ~= 0 or 1 or 2)  {
        print " ";
        DeathMessage();
        print " ";
    }
    print "***";
    #Ifdef TARGET_ZCODE;
    #IfV5; style roman; #Endif; ! V5
    #Ifnot; ! TARGET_GLULX
    glk($0086, 0); ! set normal style
    #Endif; ! TARGET_
    #Ifdef NO_SCORE;
    print "^^";
    #Ifnot;
    print "^^^";
    #Endif; ! NO_SCORE
    rfalse;
];

[ AfterGameOver; quit; ]; -).	

Part 2 - Player commands

Chapter 1 - Game engine metacommands

Section 1 - Joining

[TODO: Rewrite this in I6 so it can treat the digits as characters instead of strings.]
To decide which number is numeric value of (T - indexed text):
	let S be 1;
	let L be the number of characters in T;
	if L is 0, decide on 0;
	let negated be false;
	if character number 1 in T is "-" begin;
		let negated be true;
		let S be 2;
	end if;
	let result be 0;
	repeat with N running from S to L begin;
		let C be character number N in T;
		let D be 0;
		if C is "1" begin; let D be 1; otherwise if C is "2"; let D be 2;
		otherwise if C is "3"; let D be 3; otherwise if C is "4"; let D be 4;
		otherwise if C is "5"; let D be 5; otherwise if C is "6"; let D be 6;
		otherwise if C is "7"; let D be 7; otherwise if C is "8"; let D be 8;
		otherwise if C is "9"; let D be 9; otherwise if C is "0"; let D be 0;
		otherwise; decide on 0; end if;
		let result be (result * 10) + D;
	end repeat;
	if negated is true, let result be 0 - result;
	decide on result.

Player joining is an object-based rulebook. The player joining rulebook has a PC called the current PC.

Section 2 - Leaving

Player leaving is an object-based rulebook. The player leaving rulebook has a PC called the current PC.

Object-homing relates various things to one thing (called the object-home). The verb to be at home in implies the object-homing relation.

When play begins (this is the initial object homes rule):
	repeat with X running through things begin;
		now X is at home in the holder of X;
	end repeat.

To send (X - a thing) home:
	tell "[The X] disappears." to everyone who can see X;
	move X to the object-home of X;
	tell "[The X] appears." to everyone who can see X.

Section 3 - Polling for info

[omitted]

Chapter 2 - Chat commands

The text spoken is an indexed text that varies.
The chat direction is an indexed text that varies.

Chatting is an action applying to nothing.

Carry out chatting:
	say "You say[chat direction], '[the text spoken]'".

Emoting is an action applying to nothing.

Carry out emoting:
	if the text spoken matches the regular expression "^<.,:;!?[apostrophe]>", let space be "";
	otherwise let space be " ";
	let the full emote be indexed text;
	let the full emote be "[The player][space][the text spoken]";
	say the full emote.

Answering is speech action. Telling someone about something is speech action. Asking someone about something is speech action. 

Instead of speech action when the noun is a PC, say "As you speak the same language, you might as well speak aloud. (Just a ' mark followed by what you'd like to say will suffice.)" 

Quietly idling is an action out of world, applying to nothing. Understand "qidle" as quietly idling.

[ chat commands for the mockup... ]

Understand the command "say" as something new.

Saying is an action applying to one topic. Understand "say [text]" as saying.

Check saying:
	change the text spoken to the topic understood;
	try chatting instead.

Pre-emoting is an action applying to one topic. Understand "emote [text]" or "pose [text]" as pre-emoting.

Check pre-emoting:
	change the text spoken to the topic understood;
	try emoting instead.

After reading a command:
	let cmd be indexed text;
	let cmd be the player's command;
	replace the regular expression "^'" in cmd with "say ";
	replace the regular expression "^:" in cmd with "emote ";
	change the text of the player's command to cmd.

Chapter 3 - Modified Inform actions

This is the new other people looking rule:
	if the actor is not the player and the actor is not a PC, say "[The actor] looks around."

The new other people looking rule is listed instead of the other people looking rule in the report looking rules.

This is the new other people examining rule:
	if the actor is not the player and the actor is not a PC, say "[The actor] looks closely at [the noun]."

The new other people examining rule is listed instead of the report other people examining rule in the report examining rulebook.

Report waiting (this is the new report waiting rule):
    stop the action with library message waiting action number 1 for the player.

The standard report waiting rule is not listed in any rulebook.

The block thinking rule is not listed in any rulebook.

Report thinking:
	say "You contemplate your situation."

Report someone thinking:
	say "[The actor] pauses for a moment, lost in thought."

The block waving hands rule is not listed in any rulebook.

Report an actor waving when the actor is not the player:
	say "[The actor] waves brightly!"

Report waving hands:
	say "You wave."

Report someone waving hands:
	say "[The actor] waves."

The block smelling rule is not listed in any rulebook.

Report smelling:
	say "You smell nothing unexpected."

Report someone smelling:
	say "[The actor] sniffs[if the noun is the player] you[otherwise if the noun is not the location] [the noun][end if]."

The block listening rule is not listed in any rulebook.

Report listening:
	say "You hear nothing unexpected."

Report someone listening:
	say "[The actor] listens[if the noun is the player] to you[otherwise if the noun is not the location] to [the noun][end if]."

The block tasting rule is not listed in any rulebook.

Report tasting: 
	say "You taste nothing unexpected."

Report someone tasting:
	say "[The actor] licks [if the noun is the player]you[otherwise][the noun][end if]."

The block jumping rule is not listed in any rulebook.

Report jumping:
	say "You jump on the spot, fruitlessly." 

Report someone jumping:
	say "[The actor] jumps."

The block rubbing rule is not listed in any rulebook.

Check an actor rubbing a person:
	if the actor is the player, say "That seems intrusively personal." instead;
	stop the action.

Report rubbing:
	say "You achieve nothing by this."

Report someone rubbing:
	say "[The actor] rubs [the noun]." instead. 

The block singing rule is not listed in any rulebook.

Report singing:
	say "You sing a beautiful tune."

Report someone singing:
	say "[The actor] assails your ears with an out-of-tune ditty."

[Check quitting the game: say "To disconnect, just type 'quit' by itself." instead.
Check saving the game: say "Saving the game state is not permitted." instead.
Check restoring the game: say "Restoring a saved game is not permitted." instead.
Check restarting the game: say "Restarting the game is not permitted." instead.
Check switching the story transcript on: say "Transcripting is not permitted." instead.
Check switching the story transcript off: say "Transcripting is not permitted." instead.
Check preferring abbreviated room descriptions: say "Changing the room description setting is not permitted." instead.
Check preferring unabbreviated room descriptions: say "Changing the room description setting is not permitted." instead.
Check preferring sometimes abbreviated room descriptions: say "Changing the room description setting is not permitted." instead.
Check switching score notification on: say "Changing the score notification setting is not permitted." instead.
Check switching score notification off: say "Changing the score notification setting is not permitted." instead.

Understand "undo" as a mistake ("Sorry, undo is not available.").
Understand "oops" as a mistake ("Don't worry about it.").
Understand "oops [text]" as a mistake ("Sorry, typo correction is not available.").]

Chapter 4 - Player interactions

Section 1 - Giving items to other players

Generosity relates various things to one PC (called the potential recipient). The verb to be offered to implies the generosity relation.

Definition: a thing is offered if it is offered to the person asked.

Accepting is an action applying to one thing. Understand "accept [something offered]" as accepting. Understand "accept [something]" as accepting.

Check giving something to a PC (this is the translate giving to offering rule): try offering the noun to the second noun instead. The translate giving to offering rule is listed before the block giving rule in the check giving it to rules. The translate giving to offering rule is listed after the can't give to a non-person rule in the check giving it to rules.

Offering it to is an action applying to two things.

Carry out offering it to:
	now the noun is offered to the second noun.

Report offering it to:
	say "You offer [the noun] to [the second noun]."

Report someone offering:
	if the second noun is the player, say "[The actor] offers you [a noun]. (To accept it, type 'accept [the noun]'.)";
	otherwise say "[The actor] offers [the noun] to [the second noun]."

The accepting action has a person called the person offering (matched as "from").

Setting action variables for accepting:
	if the noun is enclosed by a person (called the current holder), now the person offering is the current holder.

Check accepting a person:
	say "You resolve to accept [the noun] as a person, faults and all." instead.

Check accepting something which is not offered to the player:
	say "[The noun] is not being offered to you." instead.

Carry out accepting:
	now the player carries the noun;
	now the noun is not offered to anyone.

Report accepting something:
	say "You accept [the noun][if the person offering is a person] from [the person offering][end if]."

Report someone accepting something:
	say "[The actor] accepts [the noun][if the person offering is the player] from you[otherwise if the person offering is a person] from [the person offering][end if]."

Every turn (this is the cancel expired offers rule):
	repeat with item running through things that are offered to someone begin;
		if the potential recipient of the item cannot see the item, now the item is not offered to anyone;
	end repeat.

Section 2 - Showing items to other players

The block showing rule is not listed in any rulebook.

Report showing something to someone:
say "You hold up [the noun] for [the second noun] to see."

Report someone showing something to someone:
	say "[The actor] holds up [the noun] for ";
	if the second noun is the player
	begin;
		say "you to see. [run paragraph on]"; 
		try examining the noun;
	otherwise;
		say "[the second noun] to see.";
	end if.

Part 3 - Multi-realm awareness

Chapter 1 - Sending the player away

To send (victim - a PC) to (destination - text):
	say "{Sending [the victim] to '[destination]'}";
	say line break.

Chapter 2 - Entrances

Table of Entrances
entrance room	entrance token
a room		"default"

When play begins (this is the initialize default entrance rule):
	repeat with R running through rooms begin;
		choose the row with entrance token of "default" in the Table of Entrances;
		change the entrance room entry to R;
		continue the action;
	end repeat.

To decide whether (T - indexed text) is a valid entrance token:
	repeat through the Table of Entrances begin;
		if T is the entrance token entry, decide yes;
	end repeat;
	decide no.

To decide which room is entrance corresponding to (T - indexed text):
	repeat through the Table of Entrances begin;
		if T is the entrance token entry, decide on the entrance room entry;
	end repeat;
	decide on nothing.

To decide which text is entrance token corresponding to (R - room):
	repeat through the Table of Entrances begin;
		if R is the entrance room entry, decide on the entrance token entry;
	end repeat;
	decide on "!".

To decide which object is closest entrance to (R - room):
	let the shortest distance be 10000;
	repeat through the Table of Entrances begin;
		let the candidate be the entrance room entry;
		let D be the number of moves from the candidate to R, using doors;
		if D is 0, decide on the candidate;
		if D is not -1 and D is less than the shortest distance begin;
			let the shortest distance be D;
			let the result be the candidate;
		end if;
	end repeat;
	decide on the result.

To say entrance path to (obj - something):
	let R be the location of obj;
	let E be the closest entrance to R;
	if E is not a room begin;
		say "!";
		stop;
	end if;
	say "=[entrance token corresponding to E]";
	while E is not R begin;
		let thataway be the best route from E to R, using doors;
		say ",[thataway in short form]";
		let E2 be the room-or-door thataway from E;
		if E2 is a door, let E be the other side of E2 from E;
		otherwise let E be E2;
	end while;
	while E is not the holder of obj begin;
		if E holds something (called the next level) which encloses obj begin;
			say ",%[next level]";
			let E be the next level;
		otherwise;
			say ",!";
			stop;
		end if;
	end while.

To say (D - direction) in short form:
	(- print (address) ({D}.&name)-->0; -).

[BUGFIX: the type of "obj" should be a thing, not an object.]
To move (obj - an object) along entrance path (path - indexed text):
	while path is not "" begin;
		if path matches the regular expression "^(<^,>*)(?:,(.*))?$" begin;
			let token be the text matching subexpression 1;
			let path be the text matching subexpression 2;
			if token matches the regular expression "^=(.*)$" begin;
				[ move to entrance ]
				let E be the entrance corresponding to the text matching subexpression 1;
				if E is a room, move obj to E;
				otherwise stop;
			otherwise if token matches the regular expression "^%(.*)$";
				[ move into container/supporter ]
				let C be the thing near obj known as the text matching subexpression 1;
				if C is a thing, move obj to C;
				otherwise stop;
			otherwise if token is "!";
				[ error ]
				stop;
			otherwise;
				[ move in the named direction ]
				let thataway be the direction known as token;
				if thataway is a direction begin;
					let the target be the bugfixed room-or-door thataway from the location of obj;
					if the target is a room, move obj to the target;
					if the target is a door, move obj to the other side of the target from the location of obj;
				otherwise;
					stop;
				end if;
			end if;
		end if;
	end while.

[BUGFIX: this phrase is a shim to avoid the resolver bug, which seems to be necessary even though "room __ from __" doesn't have an indexed text parameter.]
To decide which object is bugfixed room-or-door (dir - an object) from (source - an object):
	let result be the room-or-door dir from source;
	decide on result.

[BUGFIX: this phrase is a shim to avoid the resolver bug, which seems to be necessary even though "other side of __ from __" doesn't have an indexed text parameter.]
To decide which object is bugfixed other side of (portal - an object) from (source - an object):
	let result be the other side of the portal from the source;
	decide on result.

[BUGFIX: the type of "obj" should be a thing, not an object.]
To decide which object is the thing near (obj - an object) known as (name - indexed text):
	let L be the list of objects called name near obj;
	if the number of entries of L is 0, decide on nothing;
	otherwise decide on entry 1 of L.

[BUGFIX: the type of "obj" should be a thing, not an object.]
To decide which object is the direction known as (name - indexed text):
	let L be the list of objects called name near the north;
	if the number of entries of L is 0, decide on nothing;
	otherwise decide on entry 1 of L.

Include (- [ GetMatchList pov text list  i t rv pov2;
	if (parsetoken_nesting > 0) {
		! save match globals
		@push match_from; @push match_length;
		@push number_of_classes;
		for (i=0: i<number_matched: i++) {
			t = match_list-->i; @push t;
			t = match_classes-->i; @push t;
			t = match_scores-->i; @push t;
		}
		@push number_matched;
		@push scope_reason; @push parser_inflection;
	 }

	parsetoken_nesting++;
	SwitchBufferIn(text);
	match_length = 0; number_matched = 0; match_from = 1; scope_reason = PARSING_REASON; parser_inflection = name;
	SearchScope(ScopeCeiling(pov), pov, NOUN_TOKEN);
	SwitchBufferOut();
	rv = I7ListFromMatchList(list);
	parsetoken_nesting--;

	if (parsetoken_nesting > 0) {
		! restore match globals
		@pull parser_inflection; @pull scope_reason;
		@pull number_matched;
		for (i=0: i<number_matched: i++) {
 			@pull t; match_scores-->i = t;
			@pull t; match_classes-->i = t;
			@pull t; match_list-->i = t;
   		}
		@pull number_of_classes;
		@pull match_length; @pull match_from;
	}
	return rv;
];

[ SwitchBufferIn text  i;
	for ( i=0: i<INPUT_BUFFER_LEN: i++ )
		buffer2->i = buffer->i;
	num_words = WordCount();
	I7_IT_SetPlayersCommand(text);
];

[ SwitchBufferOut  i;
	for ( i=0: i<INPUT_BUFFER_LEN: i++ )
		buffer->i = buffer2->i;
	Tokenise__(buffer, parse);
	num_words = WordCount();
	I7_command = 100 + WordCount();
];

[ I7ListFromMatchList list desc obj dsize ex len i;
	if ((list==0) || (I7_Blk_Type(list) ~= LIST_OF_TY)) return false;
	ex = I7_Blk_Get_Extent(list);
	len = number_matched;
	if (len+LIST_ENTRY_BASE > ex) {
		if (I7_Blk_Change_Extent(list, len+LIST_ENTRY_BASE) == false)
			return 0;
	}
	I7_Blk_Put(list, BASE_KIND_F, OBJECT_TY);
	I7_Blk_Put(list, LIST_LENGTH_F, len);
	for ( i=0: i<len: i++ )
		I7_Blk_Put(list, i+LIST_ENTRY_BASE, match_list-->i);
	return list;
]; -).

To decide what list of objects is the list of objects called (name - indexed text) near (pov - object): (- GetMatchList({pov},{-pointer-to:name},{-pointer-to-new:LIST_OF_TY}) -).

Chapter 3 - Server registers

To decide which number is server register (register name - text): decide on -1.
To change server register (register name - text) to (new value - number):
	say "{Changing numeric server register '[register name]' to [new value]}";
	say line break.

To decide which indexed text is server text register (register name - text): decide on "".
To change server text register (register name - text) to (new value - indexed text):
	say "{Changing server text register '[register name]' to '[new value]'}";
	say line break.

[BUGFIX: "subject" parameter type]
To decide which indexed text is player attribute (attribute name - text) of (subject - object): decide on "".

[BUGFIX: "subject" parameter type]
To change player attribute (attribute name - text) of (subject - object) to (new value - indexed text):
	say "{Changing player attribute '[attribute name]' of [the subject] to '[new value]'}";
	say line break.

Chapter 4 - Real-time events

Real-time event is a rulebook.

To request real-time events every (N - number) seconds:
	say "{Requesting real-time events every [N] seconds}";
	say line break.

To stop real-time events:
	say "{Stopping real-time events}";
	say line break.

[ rte trigger for mockup ... ]

Triggering real-time events is an action applying to nothing. Understand "event" as triggering real-time events.

Carry out triggering real-time events:
	say "{Triggering real-time events}";
	say line break;
	follow the real-time event rules.

Guncho Mockup by Guncho Cabal ends here.
